package com.koron.housing.apply.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.PageInfo;
import com.koron.bean.query.OrderItem;
import com.koron.bean.query.PageQuery;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.housing.admin.service.HousingAdminService;
import com.koron.housing.apply.bean.dto.HousingStaffApplyDTO;
import com.koron.housing.apply.bean.dto.HousingStaffIntoDTO;
import com.koron.housing.apply.bean.po.HousingStaffApply;
import com.koron.housing.apply.bean.po.HousingStaffInto;
import com.koron.housing.apply.bean.query.HousingApplyQuery;
import com.koron.housing.apply.bean.vo.HousingStaffIntoVO;
import com.koron.housing.apply.mapper.HousingStaffIntoMapper;
import com.koron.housing.apply.service.HousingStaffApplyService;
import com.koron.housing.apply.service.HousingStaffIntoService;
import com.koron.housing.staff.service.HousingStaffService;
import org.apache.commons.collections4.CollectionUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * 入住申请(HousingStaffInto)表服务实现类
 *
 * @author jzp
 * @since 2022-02-26 14:55:11
 */
@Service("intoService")
public class HousingStaffIntoServiceImpl implements HousingStaffIntoService {

    @Autowired
    private HousingStaffApplyService applyService;
    @Autowired
    private HousingAdminService adminService;
    @Autowired
    private HousingStaffService staffService;

    private String getCurrAccount() {
        return ThreadLocalContext.get().getAccount();
    }

    /**
     * 通过ID查询单条数据
     */
    @Override
    @TaskAnnotation("getById")
    public HousingStaffInto getById(SessionFactory factory, String id) {
        HousingStaffIntoMapper mapper = factory.getMapper(HousingStaffIntoMapper.class);
        return mapper.selectById(id);
    }

    @Override
    @TaskAnnotation("getVoById")
    public HousingStaffIntoVO getVoById(SessionFactory factory, String id) {
        HousingStaffIntoMapper mapper = factory.getMapper(HousingStaffIntoMapper.class);
        return mapper.selectVoById(id);
    }

    @Override
    @TaskAnnotation("getDtoById")
    public HousingStaffIntoDTO getDtoById(SessionFactory factory, String id) {
        HousingStaffIntoVO housingStaffIntoVO = getVoById(factory, id);
        HousingStaffIntoDTO intoDTO = BeanUtil.toBean(housingStaffIntoVO, HousingStaffIntoDTO.class);
        HousingStaffApplyDTO applyDTO = applyService.getDtoById(factory, intoDTO.getApplyId());
        intoDTO.setApplyDTO(applyDTO);
        return intoDTO;
    }

    /**
     * 查询所有数据
     */
    @Override
    @TaskAnnotation("list")
    public List<HousingStaffIntoVO> list(SessionFactory factory, HousingApplyQuery query) {
        HousingStaffIntoMapper mapper = factory.getMapper(HousingStaffIntoMapper.class);
        return mapper.selectVoList(query);
    }

    @Override
    @TaskAnnotation("page")
    public PageInfo<HousingStaffIntoVO> page(SessionFactory factory, PageQuery pageQuery, HousingApplyQuery query) {
        // 如果不是过渡房管理员，需要setAccount
        if (!StringUtils.isEmpty(query.getHandler())) {
            query.setAccount(query.getHandler());
        }
        if (StringUtils.isEmpty(query.getAccount())) {
            boolean isAdmin = adminService.isAdmin(factory, getCurrAccount());
            query.setAccount(isAdmin ? null : getCurrAccount());
            query.setHandler(isAdmin ? null : getCurrAccount());
        }
        // 默认按申请单（状态（低到高）、创建时间（低到高））排序
        if (CollectionUtils.isEmpty(pageQuery.getOrders())) {
            pageQuery.getOrders().add(new OrderItem("status", true));
            pageQuery.getOrders().add(new OrderItem("createTime", true));
        }
        pageQuery.unPrefixOrders("housingStaffInto", Arrays.asList("currNodeName", "currNodeUser"));
        pageQuery.prefixOrders("housingStaffApply", Arrays.asList("account", "name", "deptId", "deptName"));
        return HousingStaffIntoService.super.page(factory, pageQuery, query);
    }

    /**
     * 新增数据
     */
    @Override
    @TaskAnnotation("save")
    public boolean save(SessionFactory factory, HousingStaffInto housingStaffInto) {
        // 如果没有状态，则为草稿状态
        if (StringUtils.isEmpty(housingStaffInto.getStatus())) {
            housingStaffInto.setStatus("0");
        }

        if (StringUtils.isEmpty(housingStaffInto.getCode())) {
            HousingStaffApply apply = applyService.getById(factory, housingStaffInto.getApplyId());
            String code = apply.getCode();
            if ("1".equals(apply.getPropertySource())) {
                code = code + "U";
            }
            housingStaffInto.setCode(code);
        }

        HousingStaffIntoMapper mapper = factory.getMapper(HousingStaffIntoMapper.class);
        return mapper.insertOrUpdate(housingStaffInto) > 0;
    }

    @Override
    @TaskAnnotation("end")
    public boolean end(SessionFactory factory, String id) {
        // 如果是公司自有租赁(非续租)，需要保存租户信息
        Optional.ofNullable(getDtoById(factory, id))
                .filter(e -> 0 == e.getIsRenewal())
                .map(HousingStaffIntoDTO::getApplyDTO)
                .filter(e -> "0".equals(e.getPropertySource()))
                .ifPresent(e-> staffService.notInto(factory, e));
        return updateStatus(factory, id, "2");
    }

    /**
     * 填写分房信息
     */
    @Override
    @TaskAnnotation("issue")
    public boolean issue(SessionFactory factory, HousingStaffInto housingStaffInto) {
        // 前端对状态2和3已经做好了控制
        save(factory, housingStaffInto);
        // 如果是续租申请，原入住申请归档（只有公司自有才有续租申请）
        if (Objects.equals(housingStaffInto.getIsRenewal(), 1)) {
            HousingStaffApply apply = applyService.getById(factory, housingStaffInto.getApplyId());
            HousingApplyQuery applyQuery = new HousingApplyQuery();
            applyQuery.setAccount(apply.getAccount());
            applyQuery.setPropertySource("0");
            applyQuery.setStatus(Collections.singletonList("3"));
            List<HousingStaffIntoVO> list = list(factory, applyQuery);
            if (!CollectionUtils.isEmpty(list)) {
                for (HousingStaffIntoVO housingStaffIntoVO : list) {
                    // 不包括自己
                    if (Objects.equals(housingStaffIntoVO.getId(), housingStaffInto.getId())) {
                        continue;
                    }
                    updateStatus(factory, housingStaffIntoVO.getId(), "4");
                    applyService.updateStatus(factory, housingStaffIntoVO.getApplyId(), "3");
                }
            }
        }
        // 保存或更新租户信息
        return staffService.into(factory, getDtoById(factory, housingStaffInto.getId()));
    }

    /**
     * 修改数据
     */
    @Override
    @TaskAnnotation("update")
    public boolean update(SessionFactory factory, HousingStaffInto housingStaffInto) {
        HousingStaffIntoMapper mapper = factory.getMapper(HousingStaffIntoMapper.class);
        return mapper.update(housingStaffInto) > 0;
    }

    @Override
    @TaskAnnotation("updateStatus")
    public boolean updateStatus(SessionFactory factory, String id, String status) {
        // 如果是公司自有，申请信息的状态应该和入住信息状态保持一致，只有0，1，2才需要如此
        HousingStaffIntoVO source = getVoById(factory, id);
        if ("0".equals(source.getPropertySource()) && Integer.parseInt(status) < 3 ) {
            applyService.updateStatus(factory, source.getApplyId(), status);
        }
        HousingStaffInto housingStaffInto = new HousingStaffInto();
        housingStaffInto.setId(id);
        housingStaffInto.setStatus(status);
        return update(factory, housingStaffInto);
    }

    /**
     * 通过主键删除数据
     */
    @Override
    @TaskAnnotation("deleteById")
    public boolean deleteById(SessionFactory factory, String id) {
        HousingStaffIntoMapper mapper = factory.getMapper(HousingStaffIntoMapper.class);
        return mapper.hidden(id) > 0;
    }
}
